
#include "register_init.h"

multicast_context g_multicast_context_ = {0};

// mac_table *total_mac_table[MAX_NODE_NUM];

// 计算检验和
unsigned short ip_csum(unsigned short *packet, int packlen)
{
  register unsigned long sum = 0;

  // 求和
  while (packlen > 1)
  {
    sum += *(packet++);
    packlen -= 2;
  }

  // 因为两个字节合并unsigned
  // short整型做计算，所以如果报文大小为奇数字节则单独加上最后一个字节的数据
  if (packlen > 0)
    sum += *(unsigned char *)packet;

  /* TODO: this depends on byte order */

  // 如果存在溢出则截断高16位数据与低16位数据求和，如sum=0x0102030405
  // 则sum=0x02030405 + 0x00000001
  while (sum >> 16)
    sum = (sum & 0xffff) + (sum >> 16);

  // sum取反码
  // printf("ip checksum:0x%04x\n", (unsigned short)~sum);
  return (unsigned short)~sum;
}

// 更新动态路由
int update_port(int node_id)
{
  u8 local_mac[6];
  get_hcp_mac_from_mid(local_mac, node_id);
  int ret = 0;
  u8 *pkt = NULL;
  u32 *data = NULL;
  u16 data_num = 0;
  u32 addr = 0; // 配置的地址
  u8 check_bit = 0;
  u32 offset = 10;

  // 读出寄存器对应的bit位(动态路由为10)
  check_bit = g_multicast_context_.node_multicast_context[node_id]->check_info.check_flag & (0x00000001 << 10);
  // 上一个周期内未收到配置响应报文
  if (check_bit)
  {
    // printf("check error: No response pkt is received in a synchronization period\n");
    // printf("hcp_mid = %d, reg_addr = %d\n", hcp_mid, reg_addr);
    write_debug_msg("check error: No response pkt is received in a synchronization period\n");
    write_debug_msg("hcp_mid = %d, reg_addr = %x\n", node_id, DROUTE_PORTBM);
  }

  // 清空pkt
  pkt = (u8 *)malloc(MAX_PKT_LEN);
  bzero(pkt, MAX_PKT_LEN);

  // data内容直接放到pkt中，省去再次赋值
  data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data)); // 配置的数据

  data[0] = htonl(g_multicast_context_.node_multicast_context[node_id]->route_port_info.dynamic_route_port);
  printf("dynamic_route:%x\n", g_multicast_context_.node_multicast_context[node_id]->route_port_info.dynamic_route_port);

  addr = DROUTE_PORTBM; // 动态路由端口寄存器
  data_num = 1;
  tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求

  // 保存此次配置的数据
  memcpy((u8 *)(g_multicast_context_.node_multicast_context[node_id]->check_info.buf) + 10 * offset, pkt + sizeof(tsmp_header), 10);

  // 读寄存器数据
  tsmp_get_req(local_mac, data_num, htonl(addr), pkt); // 读请求

  // 将寄存器对应的bit位置1
  g_multicast_context_.node_multicast_context[node_id]->check_info.check_flag |= (0x00000001 << 10);

  free(pkt);
  return 0;
}

// 更新组播转发表
int update_table(int node_id, int table_id)
{
  u8 local_mac[6];
  get_hcp_mac_from_mid(local_mac, node_id);
  int ret = 0;
  u8 *pkt = NULL;
  u32 *data = NULL;
  u16 data_num = 0;
  u32 addr = 0; // 配置的地址
  u8 check_bit = 0;
  u32 offset = 10;

  // 读出寄存器对应的bit位(转发表为0~7)
  check_bit = g_multicast_context_.node_multicast_context[node_id]->check_info.check_flag & (0x00000001 << table_id);
  // 上一个周期内未收到配置响应报文
  if (check_bit)
  {
    // printf("check error: No response pkt is received in a synchronization period\n");
    // printf("hcp_mid = %d, reg_addr = %d\n", hcp_mid, reg_addr);
    write_debug_msg("check error: No response pkt is received in a synchronization period\n");
    write_debug_msg("hcp_mid = %d, reg_addr = %x\n", node_id, MULTICAST_TABLE + 4 * table_id);
  }

  // 清空pkt
  pkt = (u8 *)malloc(MAX_PKT_LEN);
  bzero(pkt, MAX_PKT_LEN);

  // data内容直接放到pkt中，省去再次赋值
  data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data)); // 配置的数据
  // 每条表项包含4个data
  data[0] = htonl(0x80000000);
  data[1] = htonl(g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[0] * 0x01000000 +
                  g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[1] * 0x00010000 +
                  g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[2] * 0x00000100 +
                  g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[3]);
  data[2] = htonl(g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->port);
  data[3] = 0;

  addr = MULTICAST_TABLE + 4 * table_id; // 组播转发表（4N）
  data_num = 4;                          // 转发表表项格式为valid(1bit)+ip(32bit)+outport(32bit)，共65bit，硬件需要3个32bit存储，保留1个空白寄存器

  tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求
  printf("node=%x,port=%x,", node_id, g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->port);
  printf("ip=%hhu.%hhu.%hhu.%hhu\n",
         g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[0],
         g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[1],
         g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[2],
         g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[table_id]->ip[3]);

  // 保存此次配置的数据
  memcpy((u8 *)(g_multicast_context_.node_multicast_context[node_id]->check_info.buf) + table_id * offset, pkt + sizeof(tsmp_header), 10);

  // 读寄存器数据
  tsmp_get_req(local_mac, data_num, htonl(addr), pkt); // 读请求

  // 将寄存器对应的bit位置1
  g_multicast_context_.node_multicast_context[node_id]->check_info.check_flag |= (0x00000001 << table_id);

  free(pkt);
  return 0;
}

// 打印转发表
void printf_multicast_table()
{
  int i = 0;
  int j = 0;

  for (i = 0; i < MAX_NODE_NUM; i++)
  {
    node_multicast *temp_node_info = g_multicast_context_.node_multicast_context[i];
    if (temp_node_info == NULL) // 节点是否存在
    {
      continue;
    }

    printf("node_id=%d \n,", i);

    for (j = 0; j < g_multicast_context_.node_multicast_context[i]->multicast_table_info.static_multicast_entry_size; j++) // 遍历转发表动态项
    {
      printf("port=%x,", g_multicast_context_.node_multicast_context[i]->multicast_table_info.table[j]->port);
      printf("ip=%hhu.%hhu.%hhu.%hhu\n",
             g_multicast_context_.node_multicast_context[i]->multicast_table_info.table[j]->ip[0],
             g_multicast_context_.node_multicast_context[i]->multicast_table_info.table[j]->ip[1],
             g_multicast_context_.node_multicast_context[i]->multicast_table_info.table[j]->ip[2],
             g_multicast_context_.node_multicast_context[i]->multicast_table_info.table[j]->ip[3]);
    }
  }
}

// 初始化配置转发表
void multicast_fwd_init(u8 *local_mac, u8 *pkt)
{
  u16 data_num = 0;
  u16 ret = 0;

  u32 addr = 0; // 配置的地址
  u32 *data = NULL;

  // 清空pkt
  bzero(pkt, 2048);

  // data内容直接放到pkt中，省去再次赋值
  data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data)); // 配置的数据

  // multicast转发表初始化，multicast转发表总共8条表项，每条表项4个寄存器，总共32个寄存器地址

  addr = MULTICAST_TABLE;
  data_num = 4 * MAX_MULTICAST_ENTRY_NUM;
  tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求

  // 配置验证
  ret = cfg_varify(local_mac, data_num, htonl(addr), pkt);

  // 配置验证失败，程序退出
  if (ret == -1)
  {
    return;
  }

  bzero(pkt, 2048);

  return;
}

// 配置转发模式
int cfg_forward_flag_reg(u8 *local_mac, u8 *pkt, u32 flag)
{
  u16 data_num = 0;
  int ret = 0;

  u32 addr = 0; // 配置的地址
  u32 *data = NULL;

  // 清空pkt
  bzero(pkt, 2048);

  // data内容直接放到pkt中，省去再次赋值
  data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data)); // 配置的数据

  data[0] = htonl(flag);

  addr = FORWARD_MODE;
  data_num = 1;
  tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求

  // 配置验证
  ret = cfg_varify(local_mac, data_num, htonl(addr), pkt);

  // 配置验证失败，程序退出
  if (ret == -1)
  {
    return -1;
  }

  return 0;
}

// 配置静态路由端口
int cfg_route_port_reg(u8 *local_mac, u8 *pkt, u32 flag)
{
  u16 data_num = 0;
  int ret = 0;

  u32 addr = 0; // 配置的地址
  u32 *data = NULL;

  // 清空pkt
  bzero(pkt, 2048);

  // data内容直接放到pkt中，省去再次赋值
  data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data)); // 配置的数据

  data[0] = htonl(flag);

  addr = SROUTE_PORTBM;
  data_num = 1;
  tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求

  // 配置验证
  ret = cfg_varify(local_mac, data_num, htonl(addr), pkt);

  // 配置验证失败，程序退出
  if (ret == -1)
  {
    return -1;
  }

  return 0;
}

// 解析转发表中的每个标签
int parse_mac_fwd_entry(cJSON *entry_json, u32 *data, u16 node_id,
                        u8 entry_id)
{
  cJSON *tmp_json = NULL;

  // 组播转发表表项格式：
  // valid(1bit)+ip(32bit)+outport(32bit)
  u32 outport = 0;
  u32 tvalue = 0;
  u8 ip[4] = {0}; // IP地址

  g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[entry_id] = (multicast_table_entry *)malloc(sizeof(multicast_table_entry));
  memset(g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[entry_id], 0, sizeof(multicast_table_entry));

  // printf("parse_mac_fwd_entry start! \n");

  if (data == NULL)
  {
    printf("parse_multicast_fwd_entry,data = NULL! \n");
    return -1;
  }

  tmp_json = cJSON_GetObjectItem(entry_json, "ip");

  if (NULL == tmp_json)
  {
    printf("can not find  ip object!\n");
    return -1;
  }
  else
  {
    sscanf(tmp_json->valuestring, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]);

    printf("ip %hhu.%hhu.%hhu.%hhu\n", ip[0], ip[1], ip[2], ip[3]);
    memcpy(g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[entry_id]->ip, ip, 4);
  }

  tmp_json = cJSON_GetObjectItem(entry_json, "outport");

  if (NULL == tmp_json)
  {
    printf("can not find  outport object!\n");
    return -1;
  }
  else
  {
    sscanf(tmp_json->valuestring, "%x", &tvalue); // 十六进制转换
    outport = tvalue;

    g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[entry_id]->port = outport;
    g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[entry_id]->valid = 1;
    g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.table[entry_id]->type = 1;

    printf("outport: %x \n", outport);
  }

  data[0] = htonl(0x80000000);
  data[1] = htonl(ip[0] * 0x01000000 + ip[1] * 0x00010000 + ip[2] * 0x00000100 + ip[3]);
  data[2] = htonl(outport);
  data[3] = 0;

  printf("parse_multicast_fwd_entry end! \n");

  return 0;
}

// 循环解析转发表
int static_multicast_cfg_and_parse_multicast_fwd(cJSON *entry_json,
                                                 u8 *local_mac, u8 *pkt,
                                                 u16 node_id)
{
  int array_num = 0;
  int i = 0;
  int ret = 0;

  u16 data_num = 0;

  u32 addr = 0; // 配置的地址
  u32 *data = NULL;
  u8 cmp_mac[6] = {0};

  u8 cur_multicast_fwd_num = 0; // 当前转发表的数量
  cJSON *tmp_json = NULL;

  // 验证是否已正确获取local_mac，如果是则可以继续运行
  if (memcmp(local_mac, cmp_mac, 6) == 0)
  {
    printf(
        "static_multicast_cfg_and_parse_multicast_fwd,error: local_mac is 0\n");
    return -1;
  }

  if (pkt == NULL)
  {
    printf("static_multicast_cfg_and_parse_multicast_fwd,pkt = NULL! \n");
    return -1;
  }

  // data内容直接放到pkt中，省去再次赋值
  data = (u32 *)(pkt + sizeof(tsmp_header) + sizeof(tsmp_set_req_or_get_res_pkt_data)); // 配置的数据

  // 有多个节点情况
  if (entry_json->type == cJSON_Array)
  {
    array_num = cJSON_GetArraySize(entry_json);
    printf("array_num = %d \n", array_num);

    if (array_num == 0)
    {
      printf("static_multicast_cfg_and_parse_multicast_fwd, array_num = 0! \n");
      return -1;
    }

    for (i = 0; i < array_num; i++)
    {
      tmp_json = cJSON_GetArrayItem(entry_json, i);

      if (!tmp_json)
      {
        printf(
            "static_multicast_cfg_and_parse_multicast_fwd entry_json error, "
            "Error before: "
            "[%s]\n",
            cJSON_GetErrorPtr());
        return -1;
      }

      if (cur_multicast_fwd_num == MAX_MULTICAST_ENTRY_NUM)
      {
        printf("multicast table cfg error! more than max multicast entry num\n");
        return -1;
      }

      // 每条表项包含4个data
      ret = parse_mac_fwd_entry(tmp_json, data, node_id, cur_multicast_fwd_num);
      // 解析失败，程序退出
      if (ret == -1)
      {
        printf("parse_mac_fwd_entry error!\n");
        return -1;
      }

      addr = MULTICAST_TABLE + 4 * cur_multicast_fwd_num;
      data_num = 4; // 转发表表项格式为valid(1bit)+ip(32bit)+outport(32bit)，共65bit，硬件需要3个32bit存储，保留1个空白寄存器

      tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求

      // 配置验证
      ret = cfg_varify(local_mac, data_num, htonl(addr), pkt);

      // 配置验证失败，程序退出
      if (ret == -1)
      {
        return -1;
      }

      cur_multicast_fwd_num++;
    }
  }
  else if (entry_json->type == cJSON_Object)
  {
    if (cur_multicast_fwd_num == MAX_MULTICAST_ENTRY_NUM)
    {
      printf("multicast table cfg error! more than max multicast entry num\n");
      return -1;
    }

    // 每条表项包含4个data
    ret = parse_mac_fwd_entry(entry_json, data, node_id, cur_multicast_fwd_num);
    // 解析失败，程序退出
    if (ret == -1)
    {
      printf("parse_multicast_fwd_entry error!\n");
      return -1;
    }

    addr = MULTICAST_TABLE + 4 * cur_multicast_fwd_num;
    data_num = 4; // 转发表表项格式为valid(1bit)+ip(32bit)+outport(32bit)，共65bit，硬件需要3个32bit存储，保留1个空白寄存器

    tsmp_set_req(local_mac, data_num, htonl(addr), pkt); // 写请求

    // 配置验证
    ret = cfg_varify(local_mac, data_num, htonl(addr), pkt);

    // 配置验证失败，程序退出
    if (ret == -1)
    {
      return -1;
    }

    cur_multicast_fwd_num++;
  }

  g_multicast_context_.node_multicast_context[node_id]->multicast_table_info.static_multicast_entry_size = cur_multicast_fwd_num;
  return 0;
}

// 获取单个节点的static_multicast信息
int static_multicast_cfg_and_parse_node_object(cJSON *node_json, u8 *pkt)
{
  u32 tvalue32 = 0;
  u16 tvalue16 = 0;
  u8 tvalue8 = 0;
  u16 hcp_mid = 0;
  int ret = 0;

  cJSON *hcp_mid_json = NULL;
  cJSON *multicast_fwd_tbl_json = NULL;
  cJSON *tmp_json = NULL;
  cJSON *entry_json = NULL;

  u8 local_mac[6] = {0};

  // 获取节点hcp_mid信息
  hcp_mid_json = cJSON_GetObjectItem(node_json, "hcp_mid");

  if (NULL == hcp_mid_json)
  {
    printf("can not find  hcp_mid object!\n");
    return -1;
  }
  else
  {
    sscanf(hcp_mid_json->valuestring, "%hx", &tvalue16);
    hcp_mid = tvalue16;

    printf("hcp_mid 0x%hx \n", hcp_mid);

    get_hcp_mac_from_mid(local_mac, hcp_mid);

    if (hcp_mid >= MAX_NODE_NUM)
    {
      printf("hcp_mid error,hcp_mid >= MAX_NODE_NUM,hcp_mid =%d", hcp_mid);
    }
    else
    {
      g_multicast_context_.node_multicast_context[hcp_mid] = (node_multicast *)malloc(sizeof(node_multicast));
      memset(g_multicast_context_.node_multicast_context[hcp_mid], 0, sizeof(node_multicast));
    }
  }

  // 获取节点配置信息
  do
  {
    tmp_json = cJSON_GetObjectItem(node_json, "forward_mode");
    if (NULL == tmp_json)
    {
      printf("can not find forward_mode object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%x", &tvalue32);
      g_multicast_context_.node_multicast_context[hcp_mid]->cfg_para_info.forward_mode = (u8)tvalue32;
      printf("node_multicast_context[%d]->cfg_para.forward_mode = %x \n", hcp_mid, tvalue32);
      ret = cfg_forward_flag_reg(local_mac, pkt, tvalue32);
      if (ret == -1)
      {
        return -1;
      }
    }

    tmp_json = cJSON_GetObjectItem(node_json, "report_restrain_enbale");
    if (NULL == tmp_json)
    {
      printf("can not find report_restrain_enbale object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hhx", &tvalue8);
      g_multicast_context_.node_multicast_context[hcp_mid]->cfg_para_info.report_restrain_enbale = tvalue8;
      printf("node_multicast_context[%d]->cfg_para.report_restrain_enbale = %hhx\n", hcp_mid, tvalue8);
    }

    tmp_json = cJSON_GetObjectItem(node_json, "member_port_aging_time");
    if (NULL == tmp_json)
    {
      printf("can not find member_port_aging_time object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hu", &tvalue16);
      g_multicast_context_.node_multicast_context[hcp_mid]->cfg_para_info.member_port_aging_time = tvalue16;
      printf("node_multicast_context[%d]->cfg_para.member_port_aging_time = %hu \n", hcp_mid, tvalue16);
    }

    tmp_json = cJSON_GetObjectItem(node_json, "route_port_aging_time");
    if (NULL == tmp_json)
    {
      printf("can not find route_port_aging_time object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hu", &tvalue16);
      g_multicast_context_.node_multicast_context[hcp_mid]->cfg_para_info.route_port_aging_time = tvalue16;
      printf("node_multicast_context[%d]->cfg_para.route_port_aging_time = %hu \n", hcp_mid, tvalue16);
    }

    tmp_json = cJSON_GetObjectItem(node_json, "quickly_leave_port");
    if (NULL == tmp_json)
    {
      printf("can not find quickly_leave_port object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%x", &tvalue32);
      g_multicast_context_.node_multicast_context[hcp_mid]->cfg_para_info.quickly_leave_port = tvalue32;
      printf("node_multicast_context[%d]->cfg_para.quickly_leave_port = 0x%x \n", hcp_mid, tvalue32);
    }

    tmp_json = cJSON_GetObjectItem(node_json, "static_route_port");
    if (NULL == tmp_json)
    {
      printf("can not find static_route_port object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%x", &tvalue32);
      g_multicast_context_.node_multicast_context[hcp_mid]->cfg_para_info.static_route_port = tvalue32;
      printf("node_multicast_context[%d]->cfg_para.static_route_port = 0x%x \n", hcp_mid, tvalue32);
      ret = cfg_route_port_reg(local_mac, pkt, tvalue32);
      if (ret == -1)
      {
        return -1;
      }
    }
  } while (0);

  // 获取节点multicast_forward_table信息
  multicast_fwd_tbl_json = cJSON_GetObjectItem(node_json, "multicast_forward_table");

  if (NULL == multicast_fwd_tbl_json)
  {
    printf("can not find  multicast_forward_table object!\n");
    return -1;
  }
  else
  {
    // 初始化组播转发表
    multicast_fwd_init(local_mac, pkt);

    entry_json = cJSON_GetObjectItem(multicast_fwd_tbl_json, "entry");
    if (NULL == entry_json)
    {
      printf("can not find  entry_json object!\n");
      return -1;
    }

    ret = static_multicast_cfg_and_parse_multicast_fwd(entry_json, local_mac, pkt, hcp_mid);
    if (ret == -1)
    {
      printf("static_multicast_cfg_and_parse_mac_fwd error!\n");
      return -1;
    }
  }

  printf("end static_multicast_cfg_and_parse_node_object!\n");

  return 0;
}

// 解析json，获取各个节点静态组播配置信息
int static_multicast_cfg_and_parse_node(char *buf, u8 *pkt)
{
  int ret = 0;
  int array_num = 0;
  int i = 0;
  u16 tvalue16 = 0;
  u8 tvalue8 = 0;
  u8 ip[4] = {0};

  cJSON *root_json = NULL;
  cJSON *static_multicast_cfg_json = NULL;

  cJSON *multicast_json = NULL;
  cJSON *node_json = NULL;
  cJSON *tmp_json = NULL;

  riprt_n(buf);
  root_json = cJSON_Parse(buf);

  if (!root_json)
  {
    printf("parse root_json error, Error before: [%s]\n", cJSON_GetErrorPtr());
    return -1;
  }

  static_multicast_cfg_json = cJSON_GetObjectItem(root_json, "multicast_cfg_para");
  if (!static_multicast_cfg_json)
  {
    printf("parse static_multicast_cfg error, Error before: [%s]\n", cJSON_GetErrorPtr());
    cJSON_Delete(root_json);
    return -1;
  }

  multicast_json = cJSON_GetObjectItem(static_multicast_cfg_json, "multicast");
  if (!multicast_json)
  {
    printf("parse multicast_json error, Error before: [%s]\n", cJSON_GetErrorPtr());
    cJSON_Delete(root_json);
    return -1;
  }

  // 解析查询器配置
  do
  {
    tmp_json = cJSON_GetObjectItem(multicast_json, "querier_enable");
    if (NULL == tmp_json)
    {
      printf("can not find querier_enable object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hhx", &tvalue8);
      g_multicast_context_.querier_info.querier_enable = tvalue8;
      printf("querier_info.querier_enable = %hhx \n", tvalue8);
    }

    tmp_json = cJSON_GetObjectItem(multicast_json, "querier_maxresptime");
    if (NULL == tmp_json)
    {
      printf("can not find querier_maxresptime object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hhu", &tvalue8);
      g_multicast_context_.querier_info.querier_maxresptime = tvalue8;
      printf("querier_info.querier_maxresptime = %hhu \n", tvalue8);
    }

    tmp_json = cJSON_GetObjectItem(multicast_json, "querier_mid");
    if (NULL == tmp_json)
    {
      printf("can not find querier_mid object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hx", &tvalue16);
      g_multicast_context_.querier_info.querier_mid = tvalue16;
      printf("querier_info.querier_mid = 0x%hx \n", tvalue16);
    }

    tmp_json = cJSON_GetObjectItem(multicast_json, "querier_period");
    if (NULL == tmp_json)
    {
      printf("can not find querier_period object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hu", &tvalue16);
      g_multicast_context_.querier_info.querier_period = tvalue16;
      printf("querier_info.querier_period = %hu \n", tvalue16);
    }

    tmp_json = cJSON_GetObjectItem(multicast_json, "querier_sip");
    if (NULL == tmp_json)
    {
      printf("can not find querier_sip object!\n");
      return -1;
    }
    else
    {
      sscanf(tmp_json->valuestring, "%hhu.%hhu.%hhu.%hhu", &ip[0], &ip[1], &ip[2], &ip[3]);
      printf("querier_info.querier_sip = %hhu.%hhu.%hhu.%hhu\n", ip[0], ip[1], ip[2], ip[3]);
      memcpy(g_multicast_context_.querier_info.querier_sip, ip, 4);
    }

  } while (0);

  // 解析节点配置
  node_json = cJSON_GetObjectItem(static_multicast_cfg_json, "node");
  if (!node_json)
  {
    printf("parse node_json error, Error before: [%s]\n", cJSON_GetErrorPtr());
    cJSON_Delete(root_json);
    return -1;
  }

  // 有多个节点情况
  if (node_json->type == cJSON_Array)
  {
    array_num = cJSON_GetArraySize(node_json);
    printf("array_num = %d \n", array_num);

    if (array_num == 0)
    {
      printf("parse_static_multicast_info, node = NULL! \n");
      cJSON_Delete(root_json);
      return -1;
    }

    for (i = 0; i < array_num; i++)
    {
      tmp_json = cJSON_GetArrayItem(node_json, i);

      if (!tmp_json)
      {
        printf("parse static_multicast_node_entry_json error, Error before: [%s]\n", cJSON_GetErrorPtr());
        cJSON_Delete(root_json);
        return -1;
      }

      // 获取单个节点的static_multicast信息
      ret = static_multicast_cfg_and_parse_node_object(tmp_json, pkt);
      if (ret == -1)
      {
        printf("static_multicast_cfg_and_parse_node_object error!\n");
        cJSON_Delete(root_json);
        return -1;
      }
    }
  }
  else if (node_json->type == cJSON_Object)
  {
    // 获取单个节点的static_multicast信息
    ret = static_multicast_cfg_and_parse_node_object(node_json, pkt);
  }

  cJSON_Delete(root_json);

  return ret;
}

// 解析初始配置xml文本,解析一个表项，配置一个表项
int static_multicast_cfg_and_parse_file(u8 *cfg_file_name, u8 *pkt)
{
  int ret = 0;

  FILE *fp;
  char *buf;
  fp = fopen(cfg_file_name, "r");

  if (fp == NULL)
  {
    printf("fopen %s error\n", cfg_file_name);
    return -1;
  }

  // 确定文件大小, 并将读取指针移回文件开始
  fseek(fp, 0, SEEK_END);
  long pos = ftell(fp);
  fseek(fp, 0, SEEK_SET);
  if (pos <= 0)
  {
    printf("%s Invalid!\n", cfg_file_name);
    fclose(fp);
    return -1;
  }

  // 根据文件大小申请内存空间, 注意这边要多申请1个字节用于存放'\0'
  buf = (char *)malloc(pos + 1);
  if (buf == NULL)
  {
    printf("No enough memory.");
    fclose(fp);
    return -1;
  }
  bzero(buf, pos + 1);

  // 读取文件内容至buff
  int nread = fread(buf, pos, 1, fp);
  if (!nread)
  {
    printf("Failed to read the config file.");
    free(buf);
    fclose(fp);
    return -1;
  }

  // 解析json，获取各个节点静态组播配置信息
  ret = static_multicast_cfg_and_parse_node(buf, pkt);

  if (buf != NULL)
  {
    free(buf);
  }

  // 关闭文件
  fclose(fp);

  return ret;
}

// 静态组播配置的入口函数
int register_init_cfg()
{
  int ret = 0;
  int i = 0;

  // 申请空间，用于构造配置报文
  u8 *pkt = NULL;
  u8 *cfg_file_name = NULL;

  pkt = (u8 *)malloc(MAX_PKT_LEN);
  if (NULL == pkt)
  {
    printf("static_multicast_cfg,malloc buf fail\n");
    return -1;
  }

  bzero(pkt, MAX_PKT_LEN);

  cfg_file_name = MULTICAST_JSON_FILE; // 静态mac配置文本

  // 初始化全网MAC转发表
  for (i = 0; i < MAX_NODE_NUM; i++)
  {
    g_multicast_context_.node_multicast_context[i] = NULL;
  }

  // 解析初始配置xml文本,解析一个表项，配置一个表项
  ret = static_multicast_cfg_and_parse_file(cfg_file_name, pkt);
  if (ret == -1)
  {
    printf("parse_multicast_cfg_xml fail\n");
    return -1;
  }

  // 释放基础配置申请的空间
  free(pkt);

  printf_multicast_table(g_multicast_context_);

  printf("*************MULTICAST_CFG_FINISH********************\n");
  write_debug_msg("*************MULTICAST_CFG_FINISH********************\n");

  return ret;
}

// 释放内存
void multicast_context_destory()
{
  node_multicast *temp_node_info = NULL;
  multicast_table_entry *temp_table_info = NULL;
  aging_time_cnt_entry *temp_time_info = NULL;
  int i = 0, j = 0, k = 0;

  for (i = 0; i < MAX_NODE_NUM; i++)
  {
    temp_node_info = g_multicast_context_.node_multicast_context[i];

    if (temp_node_info != NULL)
    {
      for (j = 0; j < MAX_MULTICAST_ENTRY_NUM; j++)
      {
        temp_table_info = temp_node_info->multicast_table_info.table[j];

        if (temp_table_info != NULL)
        {
          for (k = 0; k < MAX_PORT_NUM; k++)
          {
            temp_time_info = temp_table_info->aging_time_info.port_aging_time_info[k];

            if (temp_time_info != NULL)
            {
              free(temp_time_info);
            }

            while (!j)
            {
              temp_time_info = temp_node_info->route_port_info.aging_time_info.port_aging_time_info[k];

              if (temp_time_info != NULL)
              {
                free(temp_time_info);
              }
            }
          }
          free(temp_table_info);
        }
      }

      free(temp_node_info);
    }
  }

  return;
}
